package hueimmersive;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.UIManager;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import javax.swing.plaf.FontUIResource;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JSlider;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.Component;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import java.awt.FlowLayout;
import java.awt.Dimension;
import java.awt.Cursor;
import javax.swing.Box;
import java.awt.Font;
import java.awt.Color;
import javax.swing.ImageIcon;
import java.awt.BorderLayout;
public class UserInterface
{
private JFrame frame;
private JLabel labelConnect;
public JButton button_Stop;
public JButton button_Start;
public JButton button_Once;
private JComboBox checkbox_Format;
public JCheckBox checkbox_ShowColorGrid;
public JSlider slider_Brightness;
private JPanel panel_Brightness;
private JLabel label_BrightnessPercentage;
public JCheckBox checkbox_RestoreLight;
public JButton button_On;
public JButton button_Off;
public JSlider sSetChunks;
private JPanel panel_Chunks;
private JLabel label_ChunksNumber;
private JLabel label_AspectRatio;
private JMenuBar menubar;
private JMenu menu_Help;
private JPanel panel;
private JMenuItem menuitem_CheckForUpdates;
private JMenuItem menuitem_About;
private JLabel label_UpdateAvailable;
private JMenu menu_Settings;
private JMenuItem menuitem_Options;
private JMenuItem menuitem_Reset;
private Component rigidarea;
public ColorGridInterface cpi = new ColorGridInterface();
private JLabel label_Saturation;
private JPanel panel_Saturation;
public JSlider slider_Saturation;
private JLabel label_SaturationPercentage;
public UserInterface() throws Exception
{
setLookAndFeel();
initialize();
}
public void setEnabled(Boolean b)
{
frame.setEnabled(b);
}
private void setLookAndFeel() // set style - Required to look identical on each platform
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
UIManager.put("Label.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("Button.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("MenuBar.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("MenuItem.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("Panel.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("ToggleButton.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("RadioButton.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("CheckBox.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("ColorChooser.font", new FontUIResource("Dialog.plain", Font.PLAIN, 12));
UIManager.put("ComboBox.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("List.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("RadioButtonMenuItem.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("CheckBoxMenuItem.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("Menu.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("PopupMenu.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("OptionPane.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("ProgressBar.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("ScrollPane.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("Viewport.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("TabbedPane.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("Table.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("TableHeader.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("TextField.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("PasswordField.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("TextArea.font", new FontUIResource("Monospaced.plain", Font.PLAIN, 13));
UIManager.put("TextPane.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("EditorPane.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("TitledBorder.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
UIManager.put("ToolBar.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("ToolTip.font", new FontUIResource("Segoe UI", Font.PLAIN, 12));
UIManager.put("Tree.font", new FontUIResource("Tahoma", Font.PLAIN, 11));
}
catch(Exception e)
{
Debug.exception(e);
}
}
private void initialize() throws Exception // pre init user interface
{
frame = new JFrame();
frame.getContentPane().setBackground(Color.WHITE);
frame.setResizable(false);
frame.setTitle("Hue Immersive");
frame.setBounds(100, 100, 243, 260);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(Settings.getInteger("ui_x"), Settings.getInteger("ui_y"));
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0)
{
Debug.closeLog();
Settings.set("ui_x", frame.getX());
Settings.set("ui_y", frame.getY());
cpi.hide();
}
});
Debug.info(null, "interface initialized");
//loadMainInterface(); // uncomment to edit MainInterface in Window Builder
//loadConnectionInterface(); // uncomment to edit ConnectionInterface in Window Builder
}
public void loadConnectionInterface() throws Exception // load the connection interface
{
frame.getContentPane().setLayout(new BorderLayout(0, 0));
labelConnect = new JLabel("");
labelConnect.setHorizontalAlignment(SwingConstants.CENTER);
frame.getContentPane().add(labelConnect);
frame.setVisible(true);
setConnectState(0);
Debug.info(null, "connection-interface loaded");
}
public void setConnectState(int state) throws Exception // set different visual output
{
switch (state)
{
case 0: //blank
labelConnect.setIcon(null);
break;
case 1: //search and connect
labelConnect.setIcon(new ImageIcon(UserInterface.class.getResource("/images/hue_connect.gif")));
Thread.sleep(1500);
break;
case 2: // successfully connected
labelConnect.setIcon(new ImageIcon(UserInterface.class.getResource("/images/hue_connected.png")));
Thread.sleep(500);
loadMainInterface();
break;
case 3: // press link button
labelConnect.setIcon(new ImageIcon(UserInterface.class.getResource("/images/hue_presslinkbutton.gif")));
break;
case 4: // timeout
labelConnect.setIcon(new ImageIcon(UserInterface.class.getResource("/images/hue_timeout.png")));
break;
}
}
public void loadMainInterface() throws Exception // load the main user interface
{
// setup window
frame.getContentPane().removeAll();
frame.getContentPane().setBackground(new Color(240, 240, 240));
frame.getContentPane().setLayout(new FormLayout(new ColumnSpec[] {
ColumnSpec.decode("10dlu:grow(2)"),
ColumnSpec.decode("5dlu:grow"),
ColumnSpec.decode("5dlu:grow"),
ColumnSpec.decode("10dlu:grow(2)"),},
new RowSpec[] {
RowSpec.decode("24px:grow"),
RowSpec.decode("24px:grow"),
RowSpec.decode("24px:grow"),
RowSpec.decode("24px:grow"),
RowSpec.decode("24px:grow"),
RowSpec.decode("24px:grow"),
RowSpec.decode("24px:grow"),
RowSpec.decode("24px:grow"),}));
// Button ON
button_On = new JButton("ON");
button_On.setToolTipText("turn all lights on");
button_On.setEnabled(false);
button_On.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try
{
Main.hueControl.turnAllLightsOn();
} catch (Exception e)
{
Debug.exception(e);
}
}
});
frame.getContentPane().add(button_On, "1, 1, 2, 1, fill, center");
// Button OFF
button_Off = new JButton("OFF");
button_Off.setToolTipText("turn all lights off");
button_Off.setEnabled(false);
button_Off.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try
{
Main.hueControl.turnAllLightsOff();
} catch (Exception e)
{
Debug.exception(e);
}
}
});
frame.getContentPane().add(button_Off, "3, 1, 2, 1, fill, center");
// Setup On/Off Buttons
setupOnOffButton();
// ComboBox that holds a list with different aspect ratios
checkbox_Format = new JComboBox();
checkbox_Format.setToolTipText("set the capture area");
checkbox_Format.setModel(new DefaultComboBoxModel(new String[] {"Fullscreen", "16:9 Widescreen", "21:9 Cinema", "Borderless (Windows)", "4:3 Traditional television"}));
checkbox_Format.setSelectedIndex(Settings.getInteger("format"));
checkbox_Format.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
Settings.set("format", checkbox_Format.getSelectedIndex());
try
{
ImmersiveProcess.setStandbyOutput();
label_ChunksNumber.setText(String.valueOf(ImmersiveProcess.chunksNumX * ImmersiveProcess.chunksNumY));
}
catch (Exception e)
{
Debug.exception(e);
}
}
});
// Label "aspect ratio"
label_AspectRatio = new JLabel("aspect ratio");
frame.getContentPane().add(label_AspectRatio, "1, 2, center, center");
frame.getContentPane().add(checkbox_Format, "2, 2, 3, 1, fill, default");
// CheckBox to show the color grid (debug feature)
checkbox_ShowColorGrid = new JCheckBox(" show color grid");
checkbox_ShowColorGrid.setToolTipText("show the color/chunks grid");
checkbox_ShowColorGrid.setSelected(Settings.getBoolean("colorgrid"));
if(checkbox_ShowColorGrid.isSelected() == true)
{
cpi.show();
}
else if (checkbox_ShowColorGrid.isSelected() == false)
{
cpi.hide();
}
checkbox_ShowColorGrid.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
try
{
Settings.set("colorgrid", checkbox_ShowColorGrid.isSelected());
if(checkbox_ShowColorGrid.isSelected() == true)
{
cpi.show();
}
else if (checkbox_ShowColorGrid.isSelected() == false)
{
cpi.hide();
}
}
catch (Exception e)
{
Debug.exception(e);
}
}
});
// Label "chunks"
JLabel label_Chunks = new JLabel(" chunks");
frame.getContentPane().add(label_Chunks, "1, 3, left, center");
// Panel to hold the chunks slider and chunks amount Label
panel_Chunks = new JPanel();
panel_Chunks.setLayout(new FormLayout(new ColumnSpec[] {
ColumnSpec.decode("115px"),
ColumnSpec.decode("right:32px:grow"),},
new RowSpec[] {
RowSpec.decode("23px:grow"),}));
frame.getContentPane().add(panel_Chunks, "2, 3, 3, 1, fill, fill");
// Label chunks amount
label_ChunksNumber = new JLabel(String.valueOf(ImmersiveProcess.chunksNumX * ImmersiveProcess.chunksNumY));
panel_Chunks.add(label_ChunksNumber, "2, 1, center, center");
// Slider to set the numbers of chunks
sSetChunks = new JSlider();
sSetChunks.setSnapToTicks(true);
sSetChunks.setToolTipText("set how detailed the grid should be");
sSetChunks.setMinorTickSpacing(1);
sSetChunks.setMajorTickSpacing(1);
sSetChunks.setMaximum(30);
sSetChunks.setValue(Settings.getInteger("chunks"));
panel_Chunks.add(sSetChunks, "1, 1, center, center");
sSetChunks.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent event)
{
Settings.set("chunks", sSetChunks.getValue());
try
{
ImmersiveProcess.setStandbyOutput();
} catch (Exception e)
{
Debug.exception(e);
}
label_ChunksNumber.setText(String.valueOf(ImmersiveProcess.chunksNumX * ImmersiveProcess.chunksNumY));
}
});
// Label "brightness"
JLabel label_Brightness = new JLabel(" brightness");
label_Brightness.setToolTipText("");
label_Brightness.setHorizontalAlignment(SwingConstants.LEFT);
frame.getContentPane().add(label_Brightness, "1, 4, left, center");
// Panel to hold brightness Slider and brightness percentage Label
panel_Brightness = new JPanel();
panel_Brightness.setLayout(new FormLayout(new ColumnSpec[] {
ColumnSpec.decode("115px"),
ColumnSpec.decode("right:38px:grow"),},
new RowSpec[] {
RowSpec.decode("26px"),}));
frame.getContentPane().add(panel_Brightness, "2, 4, 3, 1, fill, fill");
// Label brightness percentage
label_BrightnessPercentage = new JLabel(Settings.getInteger("brightness") + " %");
label_BrightnessPercentage.setIconTextGap(3);
label_BrightnessPercentage.setAlignmentX(Component.CENTER_ALIGNMENT);
label_BrightnessPercentage.setHorizontalAlignment(SwingConstants.RIGHT);
panel_Brightness.add(label_BrightnessPercentage, "2, 1, center, center");
// Slider brightness
slider_Brightness = new JSlider();
slider_Brightness.setToolTipText("set how bright your lights should be");
slider_Brightness.setMinorTickSpacing(5);
slider_Brightness.setSnapToTicks(true);
slider_Brightness.setMinimum(5);
slider_Brightness.setValue(Settings.getInteger("brightness"));
slider_Brightness.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e)
{
label_BrightnessPercentage.setText(String.valueOf(slider_Brightness.getValue()) + " %");
Settings.set("brightness", slider_Brightness.getValue());
}
});
panel_Brightness.add(slider_Brightness, "1, 1, center, center");
// Label "saturation"
label_Saturation = new JLabel(" saturation");
label_Saturation.setHorizontalAlignment(SwingConstants.LEFT);
frame.getContentPane().add(label_Saturation, "1, 5, left, center");
// Panel to hold saturation Slider and saturation percentage Label
panel_Saturation = new JPanel();
frame.getContentPane().add(panel_Saturation, "2, 5, 3, 1, fill, fill");
panel_Saturation.setLayout(new FormLayout(new ColumnSpec[] {
ColumnSpec.decode("115px"),
ColumnSpec.decode("right:38px:grow"),},
new RowSpec[] {
RowSpec.decode("26px"),}));
// Slider saturation
slider_Saturation = new JSlider();
slider_Saturation.setToolTipText("set how saturated your lights should be");
slider_Saturation.setMaximum(150);
slider_Saturation.setMinorTickSpacing(5);
slider_Saturation.setMinimum(50);
slider_Saturation.setValue(Settings.getInteger("saturation"));
slider_Saturation.setSnapToTicks(true);
slider_Saturation.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e)
{
label_SaturationPercentage.setText(String.valueOf(slider_Saturation.getValue()) + " %");
Settings.set("saturation", slider_Saturation.getValue());
}
});
panel_Saturation.add(slider_Saturation, "1, 1, center, center");
// Label saturation percentage
label_SaturationPercentage = new JLabel(Settings.getInteger("saturation") + " %");
panel_Saturation.add(label_SaturationPercentage, "2, 1, center, center");
frame.getContentPane().add(checkbox_ShowColorGrid, "1, 6, 4, 1");
// CheckBox restore light
checkbox_RestoreLight = new JCheckBox(" restore light (experimental v1)");
checkbox_RestoreLight.setToolTipText("restore the color/brightness from your lights when the program stopped");
checkbox_RestoreLight.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
Settings.set("restorelight", checkbox_RestoreLight.isSelected());
}
});
checkbox_RestoreLight.setSelected(Settings.getBoolean("restorelight"));
frame.getContentPane().add(checkbox_RestoreLight, "1, 7, 4, 1");
// Button stop
button_Stop = new JButton("STOP");
button_Stop.setEnabled(false);
button_Stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev)
{
try
{
Main.hueControl.stopImmersiveProcess();
}
catch (Exception e)
{
Debug.exception(e);
}
}
});
frame.getContentPane().add(button_Stop, "1, 8, fill, center");
// Button start
button_Start = new JButton("START");
button_Start.setToolTipText("start to ");
button_Start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev)
{
try
{
Main.hueControl.startImmersiveProcess();
}
catch (Exception e)
{
Debug.exception(e);
}
}
});
frame.getContentPane().add(button_Start, "2, 8, 2, 1, default, center");
// Button once
button_Once = new JButton("ONCE");
button_Once.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev)
{
try
{
Main.hueControl.onceImmersiveProcess();
}
catch (Exception e)
{
Debug.exception(e);
}
}
});
frame.getContentPane().add(button_Once, "4, 8, default, center");
// MenuBar
menubar = new JMenuBar();
frame.setJMenuBar(menubar);
// Menu settings
menu_Settings = new JMenu(" settings ");
menubar.add(menu_Settings);
// MenuItem options
menuitem_Options = new JMenuItem("options");
menuitem_Options.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
new OptionInterface();
}
});
menu_Settings.add(menuitem_Options);
// MenuItem reset
menuitem_Reset = new JMenuItem("reset");
menuitem_Reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
try
{
// create a dialog window (ok or cancel)
Object[] options = {"OK","Cancel"};
int dialogResult = JOptionPane.showOptionDialog(frame,
"After a reset, all previous settings are lost and can't be recovered.\nThe program will be closed after reset.",
"Warning",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[1]);
if(dialogResult == JOptionPane.YES_OPTION)
{
Settings.reset(true);
}
}
catch (Exception e)
{
Debug.exception(e);
}
}
});
menu_Settings.add(menuitem_Reset);
// Menu help
menu_Help = new JMenu(" help ");
menu_Help.setHorizontalTextPosition(SwingConstants.CENTER);
menu_Help.setHorizontalAlignment(SwingConstants.CENTER);
menubar.add(menu_Help);
// MenuItem check for updates
menuitem_CheckForUpdates = new JMenuItem("check for updates");
menuitem_CheckForUpdates.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev)
{
try
{
new UpdateInterface();
} catch (Exception e)
{
Debug.exception(e);
}
}
});
menu_Help.add(menuitem_CheckForUpdates);
// MenuItem about
menuitem_About = new JMenuItem("about");
menuitem_About.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev)
{
try
{
new AboutInterface();
} catch (Exception e)
{
Debug.exception(e);
}
}
});
menu_Help.add(menuitem_About);
// Panel to hold MenuBar
panel = new JPanel();
FlowLayout flowLayout = (FlowLayout) panel.getLayout();
flowLayout.setHgap(4);
flowLayout.setAlignment(FlowLayout.RIGHT);
menubar.add(panel);
// Label for the update note
label_UpdateAvailable = new JLabel("update available");
label_UpdateAvailable.setToolTipText("klick here to open the update menu");
panel.add(label_UpdateAvailable);
label_UpdateAvailable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0)
{
try
{
new UpdateInterface();
} catch (Exception e)
{
Debug.exception(e);
}
}
});
label_UpdateAvailable.setForeground(new Color(51, 153, 255));
label_UpdateAvailable.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
label_UpdateAvailable.setHorizontalAlignment(SwingConstants.CENTER);
label_UpdateAvailable.setVisible(Main.updateAvailable);
// RigidArea to keep distance between objects
rigidarea = Box.createRigidArea(new Dimension(9, 5));
panel.add(rigidarea);
// Label version
JLabel label_Version = new JLabel("v" + Main.version);
label_Version.setEnabled(false);
panel.add(label_Version);
// complete main user interface loading and show the window
frame.setVisible(true);
Debug.info(null, "main-interface loaded");
}
public void noteUpdate() // note that an update is available
{
label_UpdateAvailable.setVisible(true);
}
public void setupOnOffButton() throws Exception // enable/disable on/off Buttons
{
if (!Main.hueControl.immersiveProcessIsActive)
{
boolean lightOn = false;
boolean lightOff = false;
for(HLight light : HBridge.lights)
{
if (light.isOn() && Settings.Light.getActive(light))
{
lightOn = true;
}
else if (!light.isOn() && Settings.Light.getActive(light))
{
lightOff = true;
}
}
if (lightOn && lightOff)
{
button_On.setEnabled(true);
button_Off.setEnabled(true);
}
else if (lightOn)
{
button_On.setEnabled(false);
button_Off.setEnabled(true);
}
else if (lightOff)
{
button_On.setEnabled(true);
button_Off.setEnabled(false);
}
}
}
}